<!DOCTYPE html>
<html lang="en">
<head>
    
    <meta charset="utf-8">
    <title>my-form/src/Base.js - Documentation</title>
    
    
    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <link type="text/css" rel="stylesheet" href="styles/prettify.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
    <script src="scripts/nav.js" defer></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav >
    
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Outline.html">Outline</a></li><li><a href="Tag.html">Tag</a></li><li><a href="TagCanvas.html">TagCanvas</a></li></ul><h3>Modules</h3><ul><li><a href="module-$ui_components_my-affix.html">$ui/components/my-affix</a></li><li><a href="module-$ui_components_my-anchor.html">$ui/components/my-anchor</a></li><li><a href="module-$ui_components_my-autocomplete.html">$ui/components/my-autocomplete</a></li><li><a href="module-$ui_components_my-avatar.html">$ui/components/my-avatar</a></li><li><a href="module-$ui_components_my-avatars.html">$ui/components/my-avatars</a></li><li><a href="module-$ui_components_my-back-top.html">$ui/components/my-back-top</a></li><li><a href="module-$ui_components_my-capture.html">$ui/components/my-capture</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-capture.html#~_renderImg">_renderImg</a></li></ul></li><li><a href="module-$ui_components_my-card-list.html">$ui/components/my-card-list</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-card-list.html#~refresh">refresh</a></li></ul></li><li><a href="module-$ui_components_my-cascader.html">$ui/components/my-cascader</a></li><li><a href="module-$ui_components_my-checkbox.html">$ui/components/my-checkbox</a></li><li><a href="module-$ui_components_my-clipboard.html">$ui/components/my-clipboard</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-clipboard.html#~copy">copy</a></li></ul></li><li><a href="module-$ui_components_my-color-picker.html">$ui/components/my-color-picker</a></li><li><a href="module-$ui_components_my-contextmenu.html">$ui/components/my-contextmenu</a></li><li><a href="module-$ui_components_my-corner-mark.html">$ui/components/my-corner-mark</a></li><li><a href="module-$ui_components_my-crud.html">$ui/components/my-crud</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-crud.html#~openAddDialog">openAddDialog</a></li><li data-type='method'><a href="module-$ui_components_my-crud.html#~refresh">refresh</a></li><li data-type='method'><a href="module-$ui_components_my-crud.html#~reload">reload</a></li></ul></li><li><a href="module-$ui_components_my-date.html">$ui/components/my-date</a></li><li><a href="module-$ui_components_my-date-picker.html">$ui/components/my-date-picker</a></li><li><a href="module-$ui_components_my-detail.html">$ui/components/my-detail</a></li><li><a href="module-$ui_components_my-detail-item.html">$ui/components/my-detail-item</a></li><li><a href="module-$ui_components_my-dialog.html">$ui/components/my-dialog</a></li><li><a href="module-$ui_components_my-drag.html">$ui/components/my-drag</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-drag.html#~getRelativeEl">getRelativeEl</a></li></ul></li><li><a href="module-$ui_components_my-drop.html">$ui/components/my-drop</a></li><li><a href="module-$ui_components_my-edit-tags.html">$ui/components/my-edit-tags</a></li><li><a href="module-$ui_components_my-editor.html">$ui/components/my-editor</a></li><li><a href="module-$ui_components_my-empty.html">$ui/components/my-empty</a></li><li><a href="module-$ui_components_my-filter.html">$ui/components/my-filter</a></li><li><a href="module-$ui_components_my-fixed.html">$ui/components/my-fixed</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-fixed.html#~resize">resize</a></li></ul></li><li><a href="module-$ui_components_my-flex.html">$ui/components/my-flex</a></li><li><a href="module-$ui_components_my-flex-item.html">$ui/components/my-flex-item</a></li><li><a href="module-$ui_components_my-flip.html">$ui/components/my-flip</a></li><li><a href="module-$ui_components_my-float.html">$ui/components/my-float</a></li><li><a href="module-$ui_components_my-float-item.html">$ui/components/my-float-item</a></li><li><a href="module-$ui_components_my-form.html">$ui/components/my-form</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-form.html#~reset">reset</a></li><li data-type='method'><a href="module-$ui_components_my-form.html#~submit">submit</a></li></ul></li><li><a href="module-$ui_components_my-form_src_Base.html">$ui/components/my-form/src/Base</a></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html">$ui/components/my-form/src/common/TagInput</a></li><li><a href="module-$ui_components_my-form_src_common_TagSelect.html">$ui/components/my-form/src/common/TagSelect</a></li><li><a href="module-$ui_components_my-form_src_common_TreeSelect.html">$ui/components/my-form/src/common/TreeSelect</a></li><li><a href="module-$ui_components_my-grid-layout.html">$ui/components/my-grid-layout</a></li><li><a href="module-$ui_components_my-header.html">$ui/components/my-header</a></li><li><a href="module-$ui_components_my-highlight.html">$ui/components/my-highlight</a></li><li><a href="module-$ui_components_my-icon.html">$ui/components/my-icon</a></li><li><a href="module-$ui_components_my-img-text.html">$ui/components/my-img-text</a></li><li><a href="module-$ui_components_my-input.html">$ui/components/my-input</a></li><li><a href="module-$ui_components_my-input-number.html">$ui/components/my-input-number</a></li><li><a href="module-$ui_components_my-layout.html">$ui/components/my-layout</a></li><li><a href="module-$ui_components_my-lazy.html">$ui/components/my-lazy</a></li><li><a href="module-$ui_components_my-list.html">$ui/components/my-list</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-list.html#~load">load</a></li><li data-type='method'><a href="module-$ui_components_my-list.html#~refresh">refresh</a></li><li data-type='method'><a href="module-$ui_components_my-list.html#~reset">reset</a></li><li data-type='method'><a href="module-$ui_components_my-list.html#~scrollTop">scrollTop</a></li></ul></li><li><a href="module-$ui_components_my-marquee.html">$ui/components/my-marquee</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-marquee.html#~pause">pause</a></li><li data-type='method'><a href="module-$ui_components_my-marquee.html#~start">start</a></li><li data-type='method'><a href="module-$ui_components_my-marquee.html#~stop">stop</a></li></ul></li><li><a href="module-$ui_components_my-menu.html">$ui/components/my-menu</a></li><li><a href="module-$ui_components_my-navbar.html">$ui/components/my-navbar</a></li><li><a href="module-$ui_components_my-navbar-FullScreenAction.html">$ui/components/my-navbar-FullScreenAction</a></li><li><a href="module-$ui_components_my-navbar-IconAction.html">$ui/components/my-navbar-IconAction</a></li><li><a href="module-$ui_components_my-navbar-UserAction.html">$ui/components/my-navbar-UserAction</a></li><li><a href="module-$ui_components_my-number.html">$ui/components/my-number</a></li><li><a href="module-$ui_components_my-panel.html">$ui/components/my-panel</a></li><li><a href="module-$ui_components_my-paragraph.html">$ui/components/my-paragraph</a></li><li><a href="module-$ui_components_my-pro.html">$ui/components/my-pro</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-pro.html#~addTab">addTab</a></li><li data-type='method'><a href="module-$ui_components_my-pro.html#~closeTabs">closeTabs</a></li><li data-type='method'><a href="module-$ui_components_my-pro.html#~setTab">setTab</a></li></ul></li><li><a href="module-$ui_components_my-promise.html">$ui/components/my-promise</a></li><li><a href="module-$ui_components_my-radio.html">$ui/components/my-radio</a></li><li><a href="module-$ui_components_my-range.html">$ui/components/my-range</a></li><li><a href="module-$ui_components_my-rate.html">$ui/components/my-rate</a></li><li><a href="module-$ui_components_my-resize.html">$ui/components/my-resize</a></li><li><a href="module-$ui_components_my-result.html">$ui/components/my-result</a></li><li><a href="module-$ui_components_my-revolve.html">$ui/components/my-revolve</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-revolve.html#~next">next</a></li><li data-type='method'><a href="module-$ui_components_my-revolve.html#~prev">prev</a></li><li data-type='method'><a href="module-$ui_components_my-revolve.html#~start">start</a></li><li data-type='method'><a href="module-$ui_components_my-revolve.html#~stop">stop</a></li></ul></li><li><a href="module-$ui_components_my-select.html">$ui/components/my-select</a></li><li><a href="module-$ui_components_my-sidebar.html">$ui/components/my-sidebar</a></li><li><a href="module-$ui_components_my-skeleton.html">$ui/components/my-skeleton</a></li><li><a href="module-$ui_components_my-slider.html">$ui/components/my-slider</a></li><li><a href="module-$ui_components_my-sortable.html">$ui/components/my-sortable</a></li><li><a href="module-$ui_components_my-spin.html">$ui/components/my-spin</a></li><li><a href="module-$ui_components_my-stat-card.html">$ui/components/my-stat-card</a></li><li><a href="module-$ui_components_my-switch.html">$ui/components/my-switch</a></li><li><a href="module-$ui_components_my-table.html">$ui/components/my-table</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-table.html#~refresh">refresh</a></li></ul></li><li><a href="module-$ui_components_my-tag-canvas.html">$ui/components/my-tag-canvas</a></li><li><a href="module-$ui_components_my-tag-input.html">$ui/components/my-tag-input</a></li><li><a href="module-$ui_components_my-tag-select.html">$ui/components/my-tag-select</a></li><li><a href="module-$ui_components_my-text.html">$ui/components/my-text</a></li><li><a href="module-$ui_components_my-timer.html">$ui/components/my-timer</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-timer.html#~reset">reset</a></li><li data-type='method'><a href="module-$ui_components_my-timer.html#~start">start</a></li><li data-type='method'><a href="module-$ui_components_my-timer.html#~stop">stop</a></li></ul></li><li><a href="module-$ui_components_my-title.html">$ui/components/my-title</a></li><li><a href="module-$ui_components_my-tree-select.html">$ui/components/my-tree-select</a></li><li><a href="module-$ui_components_my-typography.html">$ui/components/my-typography</a></li><li><a href="module-$ui_components_my-watermark.html">$ui/components/my-watermark</a></li><li><a href="module-$ui_components_my-wrapper.html">$ui/components/my-wrapper</a></li><li><a href="module-widgets_my-print.html">widgets/my-print</a></li></ul><h3>Events</h3><ul><li><a href="module-$ui_components_my-stat-card.html#~event:action">action</a></li><li></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html#~event:add">add</a></li><li><a href="module-$ui_components_my-wrapper.html#~event:back">back</a></li><li><a href="module-$ui_components_my-dialog.html#~event:cancel">cancel</a></li><li><a href="module-$ui_components_my-typography.html#~event:change">change</a></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-navbar-UserAction.html#~event:click">click</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-avatars.html#~event:click-add">click-add</a></li><li><a href="module-$ui_components_my-avatars.html#~event:click-item">click-item</a></li><li><a href="module-$ui_components_my-avatars.html#~event:click-more">click-more</a></li><li><a href="module-$ui_components_my-dialog.html#~event:close">close</a></li><li><a href="module-$ui_components_my-pro.html#~event:collapse">collapse</a></li><li><a href="module-$ui_components_my-form_src_common_TagSelect.html#~event:collapsed">collapsed</a></li><li><a href="module-$ui_components_my-navbar-UserAction.html#~event:command">command</a></li><li></li><li></li><li><a href="global.html#event:complete">complete</a></li><li></li><li><a href="module-$ui_components_my-contextmenu.html#~event:contextmenu">contextmenu</a></li><li><a href="module-$ui_components_my-typography.html#event:copy">copy</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-drag.html#~event:drag">drag</a></li><li></li><li><a href="module-$ui_components_my-dialog.html#~event:drag-start">drag-start</a></li><li><a href="module-$ui_components_my-dialog.html#~event:drag-stop">drag-stop</a></li><li><a href="module-$ui_components_my-drop.html#~event:drop">drop</a></li><li><a href="module-$ui_components_my-typography.html#event:edited">edited</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-typography.html#event:editing">editing</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-drop.html#~event:enter">enter</a></li><li><a href="module-$ui_components_my-table.html#~event:error">error</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-typography.html#event:expand">expand</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-timer.html#~event:finish">finish</a></li><li><a href="module-$ui_components_my-dialog.html#~event:hide">hide</a></li><li></li><li><a href="module-$ui_components_my-lazy.html#~event:init">init</a></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html#~event:input-change">input-change</a></li><li><a href="module-$ui_components_my-grid-layout.html#~event:layout-updated">layout-updated</a></li><li><a href="module-$ui_components_my-drop.html#~event:leave">leave</a></li><li><a href="module-$ui_components_my-wrapper.html#~event:link-click">link-click</a></li><li><a href="module-$ui_components_my-dialog.html#~event:load">load</a></li><li><a href="module-$ui_components_my-revolve.html#~event:loaded">loaded</a></li><li><a href="module-$ui_components_my-dialog.html#~event:maximize">maximize</a></li><li><a href="module-$ui_components_my-contextmenu.html#~event:mouseenter">mouseenter</a></li><li></li><li><a href="module-$ui_components_my-capture.html#~event:on-capture">on-capture</a></li><li><a href="global.html#event:on-change">on-change</a></li><li><a href="module-$ui_components_my-tag-canvas.html#~event:on-click">on-click</a></li><li><a href="module-$ui_components_my-capture.html#~event:on-output">on-output</a></li><li><a href="module-$ui_components_my-dialog.html#~event:open">open</a></li><li><a href="module-$ui_components_my-drop.html#~event:over">over</a></li><li><a href="global.html#~event:page-change">page-change</a></li><li></li><li></li><li><a href="module-$ui_components_my-revolve.html#~event:progress">progress</a></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html#~event:remove">remove</a></li><li><a href="module-$ui_components_my-timer.html#~event:reset">reset</a></li><li></li><li><a href="module-$ui_components_my-resize.html#~event:resize">resize</a></li><li></li><li><a href="module-$ui_components_my-dialog.html#~event:resize-start">resize-start</a></li><li><a href="module-$ui_components_my-dialog.html#~event:resize-stop">resize-stop</a></li><li><a href="module-$ui_components_my-sidebar.html#~event:select">select</a></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-dialog.html#~event:show">show</a></li><li></li><li><a href="global.html#~event:size-change">size-change</a></li><li></li><li></li><li><a href="module-$ui_components_my-timer.html#~event:start">start</a></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-timer.html#~event:stop">stop</a></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-form.html#~event:submit">submit</a></li><li></li><li><a href="module-$ui_components_my-table.html#~event:success">success</a></li><li></li><li></li><li><a href="module-$ui_components_my-panel.html#~event:tab-change">tab-change</a></li><li><a href="module-$ui_components_my-pro.html#~event:tab-remove">tab-remove</a></li><li><a href="module-$ui_components_my-pro.html#~event:tab-select">tab-select</a></li><li><a href="module-$ui_components_my-timer.html#~event:tick">tick</a></li><li><a href="module-$ui_components_my-form.html#~event:validate">validate</a></li><li><a href="module-widgets_my-back-top.html#event:click">click</a></li></ul><h3>Global</h3><ul><li><a href="global.html#AddShadowToImage">AddShadowToImage</a></li><li><a href="global.html#appendChildNode">appendChildNode</a></li><li><a href="global.html#createEllipsisContainer">createEllipsisContainer</a></li><li><a href="global.html#createEllipsisContentHolder">createEllipsisContentHolder</a></li><li><a href="global.html#destroyVue">destroyVue</a></li><li><a href="global.html#getData">getData</a></li><li><a href="global.html#inRange">inRange</a></li><li><a href="global.html#instanceVue">instanceVue</a></li><li><a href="global.html#props">props</a></li><li><a href="global.html#pxToNumber">pxToNumber</a></li><li><a href="global.html#removeEllipsisContainer">removeEllipsisContainer</a></li><li><a href="global.html#RoundImage">RoundImage</a></li><li><a href="global.html#scrollTop">scrollTop</a></li><li><a href="global.html#setData">setData</a></li><li><a href="global.html#styleToString">styleToString</a></li><li><a href="global.html#wrapperDecorations">wrapperDecorations</a></li></ul>
</nav>

<div id="main">
    
    <h1 class="page-title">my-form/src/Base.js</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 * 表单项基础类, 所有输入组件都继承Base
 * @module $ui/components/my-form/src/Base
 */

import {FormItem} from 'element-ui'
import {setStyle} from 'element-ui/lib/utils/dom'
import {addResizeListener, removeResizeListener} from 'element-ui/lib/utils/resize-event'
import {cloneDeep, isEqual} from '$ui/utils/util'
const _get = require('lodash/get')
const _set = require('lodash/set')

/**
 * 插槽
 * @member slots
 * @property {string} before 输入组件前面的内容，仅当父组件是MyForm有效
 * @property {string} after 输入组件后面的内容，仅当父组件是MyForm有效
 * @property {string} label 定义字段的label内容，仅当父组件是MyForm有效
 * @property {string} error 作用域插槽，定义验证错误提示内容，仅当父组件是MyForm有效
 */

export default {
  inject: {
    myForm: {
      default: null
    }
  },
  components: {
    FormItem
  },
  /**
   * 属性参数
   * @member props
   * @property {string} [name] 表单域 model 字段名称, 等价于 el-form-item 的 prop 参数
   * @property {string} [width] 宽度，css属性，支持像素，百分比和表达式，也可以在MyForm中统一设置itemWidth
   * @property {object} [props] 输入组件参数对象，即 element 组件的参数
   * @property {Array} [options] 选项数据，数据优先顺序，options > loader > form.dictMap > form.loader
   * @property {Object} [keyMap] 选项数据对象属性名称映射, 默认：{id, parentId, label, value}
   * @property {boolean} [collapsible] 可收起
   * @property {boolean} [stopEnterEvent] 阻止回车事件冒泡
   * @property {string} [depend] 依赖字段名称
   * @property {*} [dependValue] 依赖字段的值，即依赖字段的值等于该值才会显示
   * @property {string} [cascade] 级联的上级字段名称，需要与loader配合加载数据
   * @property {Function} [loader] 加载数据函数,必须返回Promise
   * @property {string} [dict] 字典名称，只是标识，需要与loader配合 或 表单的dictMap加载数据
   * @property {boolean} [disabled] 禁用
   * @property {boolean} [readonly] 只读
   * @property {string} [placeholder] 占位文本
   *
   */
  props: {
    // 表单域 model 字段名称
    name: String,
    // 宽度，支持像素，百分比和表达式
    width: String,
    // 输入组件参数对象
    props: Object,
    // 选项数据，数据优先顺序，options > loader > form.dictMap > form.loader
    options: Array,
    // 选项数据对象属性名称映射
    keyMap: {
      type: Object,
      default() {
        return {
          id: 'id',
          label: 'label',
          value: 'value',
          disabled: 'disabled',
          parentId: 'parentId'
        }
      }
    },
    // 可折叠
    collapsible: Boolean,
    
    // 阻止回车事件冒泡
    stopEnterEvent: Boolean,
    
    // 依赖字段名称
    depend: String,
    
    // 依赖字段的值，即依赖字段的值等于该值才会显示
    dependValue: [String, Number, Boolean, Object, Array, Function],
    
    // 级联的上级字段名称，需要与loader配合加载数据
    cascade: String,
    
    // 加载数据函数,必须返回Promise
    loader: Function,
    
    // 字典名称，只是标识，需要与loader配合 或 表单的dictMap加载数据
    dict: String,
    
    // 禁用
    disabled: Boolean,
    // 只读
    readonly: Boolean,
    
    // 占位文本
    placeholder: String,
    
    // 尺寸
    size: String
  },
  data() {
    return {
      // 级联的值缓存
      cascadeValue: null,
      // 当前选项数据
      currentOptions: [],
      
      // 正在调用loader
      loading: false
    }
  },
  computed: {
    // 如果有name参数，并且是MyForm的子组件，即与MyForm的currentModel作双向绑定
    // 否则与组件自身的value作双向绑定
    fieldValue: {
      get() {
        if (this.name &amp;&amp; this.myForm) {
          const {currentModel} = this.myForm
          return _get(currentModel, this.name, this.getDefaultValue())
          // return (this.name in currentModel)
          //   ? currentModel[this.name]
          //   : this.getDefaultValue()
        } else {
          return this.value || this.getDefaultValue()
        }
      },
      set(val) {
        if (this.name &amp;&amp; this.myForm) {
          const model = cloneDeep(this.myForm.currentModel)
          _set(model, this.name, val)
          this.myForm.currentModel = model
          // this.$set(this.myForm, 'currentModel', model)
          // this.$set(this.myForm.currentModel, this.name, val)
        } else {
          this.$emit('input', val)
        }
      }
    },
    // 字段域的宽度
    itemWidth() {
      // 优先取自身设置的宽度，没有就取父组件设置的公共设置宽度
      return this.width || ((this.myForm &amp;&amp; this.myForm.itemWidth)
        ? this.myForm.itemWidth
        : null)
    },
    // 字段域样式
    itemStyle() {
      return {
        width: this.itemWidth
      }
    },
    // 输入框组件参数
    innerProps() {
      return {
        disabled: this.disabled,
        readonly: this.readonly,
        placeholder: this.placeholder,
        size: this.size,
        ...this.props
      }
    }
  },
  watch: {
    itemWidth: {
      immediate: true,
      handler() {
        this.$nextTick(() => {
          this.setContentWidth()
        })
      }
    },
    'myForm.currentCollapsed'(val) {
      const {resetCollapsed, model} = this.myForm
      // 收起时重置表单项值
      if (val &amp;&amp; resetCollapsed &amp;&amp; model &amp;&amp; this.collapsible) {
        this.$nextTick(() => {
          // this.fieldValue = this.myForm.model[this.name]
          this.fieldValue = _get(this.myForm.model, this.name, this.getDefaultValue())
        })
      }
      // 开启了折叠功能
      if (this.collapsible) {
        // 折叠时先要清除事件句柄，因为原先的dom即将发生改变
        if (val) {
          removeResizeListener(this.$el, this.setContentWidth)
        } else {
          // 如果没有加载过选项数据，触发加载函数
          if (!this.currentOptions || this.currentOptions.length === 0) {
            this.loadOptions(this.myForm.currentModel, this)
          }
          // 展开时，待DOM生成后，重新注册事件句柄
          this.$nextTick(() => {
            addResizeListener(this.$el, this.setContentWidth)
            this.setContentWidth()
          })
        }
      }
    },
    // options 为了提高性能，不设置deep
    options: {
      immediate: true,
      handler(val) {
        this.currentOptions = cloneDeep(val) || []
        // options改变后，会触发表单验证，这里需要清楚验证错误信息
        this.$nextTick(() => {
          this.clearValidate()
        })
      }
    }
  },
  methods: {
    // 获取表单项的默认值，不同组件有不同的默认值，可在具体的组件重写这个函数
    getDefaultValue() {
      return ''
    },
    // 重置字段
    resetField() {
      this.$refs.elItem &amp;&amp; this.$refs.elItem.resetField()
    },
    // 清除验证错误信息
    clearValidate() {
      this.$refs.elItem &amp;&amp; this.$refs.elItem.clearValidate()
    },
    isCollapsed() {
      if (!this.myForm) return false
      
      const {collapsible, currentCollapsed} = this.myForm
      // 是否已收起
      return (collapsible &amp;&amp; currentCollapsed &amp;&amp; this.collapsible)
    },
    isMatchDepend() {
      // 没有设置依赖，即忽略，当已匹配处理
      if (!this.depend || !this.myForm) return true
      const model = this.myForm.currentModel
      // 依赖不支持 按路径查找
      const value = model[this.depend]
      let isMatch = true
      // 如果 dependValue 是函数，执行回调函数返回布尔值
      if (typeof this.dependValue === 'function') {
        isMatch = this.dependValue(value, model, this)
      } else {
        // 以上都不符合，即检验 dependValue 与 currentModel中的依赖属性是否一致
        isMatch = isEqual(this.dependValue, value)
      }
      
      // 清除依赖不符合字段的值
      if (!isMatch &amp;&amp; this.name &amp;&amp; model[this.name]) {
        this.fieldValue = this.getDefaultValue()
        delete model[this.name]
      }
      
      return isMatch
    },
    // 传递给输入组件的插槽
    createSlots(slots = []) {
      return slots.map(name => {
        return &lt;template slot={name}>{this.$slots[name]}&lt;/template>
      })
    },
    // 渲染输入组件
    renderComponent(vnode) {
      // 如果组件不是MyForm的子组件，不需要包裹Item组件
      if (!this.myForm) {
        return vnode
      }
      // el-form-item 作用域插槽
      const scopedSlots = this.$scopedSlots.error
        ? {
          error: props => (
            &lt;div class="el-form-item__error my-from__custom-error">
              {this.$scopedSlots.error(props)}
            &lt;/div>
          )
        }
        : null;
      
      // 是否已收起
      const collapsed = this.isCollapsed()
      // 是否符合依赖项
      const isMatched = this.isMatchDepend()
      
      return (
        &lt;transition name={this.myForm.collapseEffect}>
          {
            (!collapsed &amp;&amp; isMatched)
              ? &lt;FormItem ref="elItem"
                          class="my-form-item"
                          {...{props: this.$attrs, scopedSlots: scopedSlots, style: this.itemStyle}}
                // 停止回车键事件冒泡
                          vOn:keyup_native_enter={this.stopEvent}
                // el-form-item 的prop用name代替
                          prop={this.name}>
                
                {
                  // label 插槽
                  this.$slots.label
                    ? &lt;template slot="label">{this.$slots.label}&lt;/template>
                    : null
                }
                {this.$slots.before}
                {vnode}
                {this.$slots.after}
              &lt;/FormItem>
              // Vue组件必须要有一个根DOM，创建一个隐藏占位元素
              : &lt;div style={{display: 'none'}}>{this.name}&lt;/div>
          }
        
        &lt;/transition>
      )
    },
    // 继承输入组件暴露的方法
    extendMethods(ref, names = []) {
      if (!ref) return
      
      names.forEach(name => {
        // 子组件的方法加到实例
        this[name] = (...args) => {
          ref[name].apply(ref, args)
        }
      })
      
    },
    // 设置el-form-item内部的内容区宽度
    setContentWidth() {
      // 字段域没有设置宽度，默认自适应，不需要处理
      if (!this.itemWidth || !this.$el) return
      const content = this.$el.querySelector('.el-form-item__content')
      const label = this.$el.querySelector('.el-form-item__label')
      if (content) {
        const rect = label ? label.getBoundingClientRect() : {width: 0}
        const itemWidth = this.$el.getBoundingClientRect().width
        const contentWidth = itemWidth - rect.width
        setStyle(content, {width: `${contentWidth}px`})
      }
    },
    // 阻止回车事件冒泡
    stopEvent(e) {
      if (this.stopEnterEvent) {
        e.stopPropagation()
      }
    },
    // 加载选项数据
    loadOptions(model) {
      // 已收起的，不需要处理
      if (this.isCollapsed()) return
      
      // 如果不符合依赖，不处理
      if (!this.isMatchDepend()) return
      
      // 数据优先顺序，options > loader > form.dictMap > form.loader
      if (this.options) {
        this.currentOptions = cloneDeep(this.options)
        return
      }
      
      if (this.loader) {
        this.loading = true
        this.loader(model, this).then(res => {
          this.currentOptions = cloneDeep(res)
        }).finally(() => {
          this.loading = false
        })
        return
      }
      
      // 无form容器，终止
      if (!this.myForm) return
      
      if (this.dict) {
        const {dictMap} = this.myForm
        const options = (dictMap || {})[this.dict]
        // 建立与表单的字典数据引用
        if (options) {
          this.currentOptions = options
          return
        }
        
      }
      
      if (this.myForm.loader) {
        this.loading = true
        this.myForm.loader(model, this).then(res => {
          this.currentOptions = cloneDeep(res)
        }).finally(() => {
          this.loading = false
        })
      }
      
    },
    // 响应currentModel改变处理级联加载数据
    handleWatch(model) {
      // 级联上级的值
      const val = model[this.cascade]
      // 与上次的值不一致即重新获取数据
      if (!isEqual(this.cascadeValue, val)) {
        this.fieldValue = this.getDefaultValue()
        this.cascadeValue = val
        this.loadOptions(model)
      }
    },
    // 绑定级联
    bindCascade() {
      if (this.cascade &amp;&amp; this.myForm) {
        const model = this.myForm.currentModel
        this.cascadeValue = model[this.cascade]
        this.unwatch = this.$watch('myForm.currentModel', this.handleWatch, {deep: true})
      }
    },
    // 销毁级联事件句柄
    unbindCascade() {
      this.unwatch &amp;&amp; this.unwatch()
    }
  },
  mounted() {
    addResizeListener(this.$el, this.setContentWidth)
  },
  created() {
    let model = null
    if (this.myForm) {
      this.myForm.addItem(this)
      model = this.myForm.currentModel
    }
    
    this.loadOptions(model, this)
    this.bindCascade()
  },
  beforeDestroy() {
    removeResizeListener(this.$el, this.setContentWidth)
    this.unbindCascade()
    if (this.myForm) {
      this.myForm.removeItem(this)
    }
  }
  
}
</code></pre>
        </article>
    </section>





    
</div>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.4</a> on Wed Jun 10 2020 17:09:13 GMT+0800 (GMT+08:00) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/polyfill.js"></script>
<script src="scripts/linenumber.js"></script>




<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?c4e5f73318b5cb0c389e3d9a05f831cc";
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);
})();
</script>

</body>
</html>
